package com.dkha.task.contral;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dkha.common.enums.ErrEnum;
import com.dkha.common.enums.SocketEnum;
import com.dkha.common.http.HttpUtil;
import com.dkha.common.modules.vo.camera.BayOnetCameraVO;
import com.dkha.common.modules.vo.camera.CameraInfoVO;
import com.dkha.common.modules.vo.dto.FaceLibraryVO;
import com.dkha.common.modules.vo.face.AlarmReturnVO;
import com.dkha.common.modules.vo.face.ApiAlarmVO;
import com.dkha.common.modules.vo.face.PageVO;
import com.dkha.common.modules.vo.warning.BayoneReturnListVO;
import com.dkha.common.modules.vo.warning.WarningPageVO;
import com.dkha.common.redis.RedisKeys;
import com.dkha.common.redis.RedisUtils;
import com.dkha.common.util.UrlUtil;
import com.dkha.common.util.UtilValidate;
import com.dkha.task.comm.TimerData;
import com.dkha.task.modual.vo.ReturnVO;
import com.dkha.task.service.ApiDeelService;
import com.dkha.task.service.IControlBayonetMidService;
import com.dkha.task.service.WebSocketContral;
import com.dkha.task.service.impl.AsyncServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @version V1.0
 * @Description: TODO(please write your description)
 * All rights 成都电科慧安
 * @Title: TimerContral
 * @Package com.dkha.task.contral
 * @author: panhui
 * @date: 2020/1/2 16:31
 * @Copyright: 成都电科慧安
 */
@Slf4j
@Component
public class TimerContral {

    @Value("${face.warning-url}")
    private String warningUrl;

    @Value("${face.bayonet-url}")
    private String bayonetUrl;

    @Autowired
    private HttpUtil httpUtil;

    @Autowired
    private WebSocketContral webSocketContral;

    @Autowired
    private Gson gson;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 预警内容的定时数据 10秒后啓動每次10毫秒運行   TODO 後續記得加上token
     */
    @Scheduled(fixedDelay = 50, initialDelay = 1000 * 10)
    public void warning() {
        try {
//            String userToken = "";
//            if (UtilValidate.isNotEmpty(redisUtils.get("token"))) {
//                userToken = (String) redisUtils.get("token");
//            } else {
//                return;
//            }
            //更改ddd
            ApiAlarmVO apiAlarmVO = new ApiAlarmVO();
//            apiAlarmVO.setToken(userToken);
            String json = UrlUtil.postData(warningUrl, apiAlarmVO, httpUtil, gson);
            if (UtilValidate.isEmpty(json)) {
                return;
            }
            Page pages = gson.fromJson(json, Page.class);
            if (TimerData.WARNING_NUM.intValue() == -1 || pages.getTotal() == 0L || TimerData.WARNING_NUM.intValue() == pages.getTotal()) {
                if (TimerData.WARNING_NUM.intValue() == -1 && pages.getTotal() != 0L) {
                    //刚启动的时候
                    TimerData.WARNING_NUM = pages.getTotal();
                }
            } else {
                Long count = pages.getTotal() - TimerData.WARNING_NUM;
                if(count<0){
                    count = 1L;
                }
                ApiAlarmVO apiVO = new ApiAlarmVO();
//                apiVO.setToken(userToken);
                PageVO pageVo = new PageVO();
                pageVo.setPageSize(count.intValue());
                apiVO.setPage(pageVo);
                String jsonData = UrlUtil.postData(warningUrl, apiVO, httpUtil, gson);
                if (UtilValidate.isNotEmpty(jsonData)) {
                    Page page = gson.fromJson(jsonData, Page.class);
                    try {
                        List<WarningPageVO> myRecords = gson.fromJson(gson.toJson(page.getRecords()), new TypeToken<List<WarningPageVO>>() {
                        }.getType());
                        myRecords.forEach(e ->
                        {
                            ReturnVO returnVO = new ReturnVO(ErrEnum.OK, e);
                            returnVO.setCmd(SocketEnum.WARNING.getCode());
                            webSocketContral.sendMessage(gson.toJson(returnVO));
                            try {
                                if (myRecords.size() > 1) {
                                    Thread.sleep(50);
                                }
                            } catch (Exception ex) {
                            }
                        });
                    } catch (Exception ex) {
                    } finally {
                        TimerData.WARNING_NUM = pages.getTotal();
                    }
                }
            }
        } catch (Exception e) {
            log.error("预警系统异常，休眠10秒再试{}", e.getMessage());
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e1) {

            }
        }
    }


    @Autowired
    private AsyncServiceImpl asyncContral;

    /**
     * 卡口数据获取  TODO 後續記得加上token
     */
    @Scheduled(fixedDelay = 40, initialDelay = 20000)
    public void bayonet() {
        try {
            TimerData.bayonetMap.forEach((a, b) ->
            {
//                String sessionId = a;
//                String userToken = "";
//                if (UtilValidate.isNotEmpty(redisUtils.get(RedisKeys.getSessionIdKey(sessionId)))) {
//                    userToken = (String) redisUtils.get(RedisKeys.getSessionIdKey(sessionId));
//                } else {
//                    return;
//                }
                ApiAlarmVO apiAlarmVO = new ApiAlarmVO();
//                apiAlarmVO.setToken(userToken);
                String json = UrlUtil.getData(bayonetUrl + "/" + b.getCarmeraId() + "/" + 1,  httpUtil, gson);

                if (UtilValidate.isEmpty(json)) {
                    return;
                }
//                if (json.length() < 4) {
//                    if (ErrEnum.UNAUTHORIZED.getCode().intValue() == Integer.valueOf(json)) {
//                        webSocketContral.sendMessage(gson.toJson(new ReturnVO(ErrEnum.UNAUTHORIZED)));
//                        TimerData.bayonetMap.remove(a);
//                        return;
//                    }
//                }

                BayoneReturnListVO bayoneReturnListVO = gson.fromJson(json, BayoneReturnListVO.class);
                if (b.getBayonetNum().intValue() == -1 || bayoneReturnListVO.getToDaySnapShot() == 0L || b.getBayonetNum() == bayoneReturnListVO.getToDaySnapShot()) {
                    if (b.getBayonetNum().intValue() == -1 && bayoneReturnListVO.getToDaySnapShot() != 0L) {
                        //刚启动的时候
                        b.setBayonetNum(bayoneReturnListVO.getToDaySnapShot());
                    }
                } else {
                    Long count = bayoneReturnListVO.getToDaySnapShot() - b.getBayonetNum();
                    String jsonData = UrlUtil.getData(bayonetUrl + "/" + b.getCarmeraId() + "/" + count,  httpUtil, gson);
                    if (UtilValidate.isNotEmpty(jsonData)) {
//                        System.out.println(bayoneReturnListVO.getToDaySnapShot() + "bayonet发现预警！" + count + "==" + b.getBayonetNum());
                        BayoneReturnListVO bayoneVO = gson.fromJson(jsonData, BayoneReturnListVO.class);
                        try {
                            List<AlarmReturnVO> myRecords = gson.fromJson(gson.toJson(bayoneVO.getResult()), new TypeToken<List<AlarmReturnVO>>() {
                            }.getType());
                            myRecords.forEach(e ->
                            {
                                e.setToDaySnapShot(bayoneVO.getToDaySnapShot());
                                e.setTotalSnapShot(bayoneVO.getTotalSnapShot());
                                ReturnVO returnVO = new ReturnVO(ErrEnum.OK, e);
                                returnVO.setCmd(SocketEnum.BAYONET.getCode());
                                asyncContral.bayonetInfo(a, gson.toJson(returnVO));
                            });
                        } catch (Exception ex) {
                        } finally {
                            b.setBayonetNum(bayoneReturnListVO.getToDaySnapShot());
                        }
                    }
                }
            });
        } catch (Exception e) {
            log.error("卡口系统异常，休眠10秒再试{}", e.getMessage());
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e1) {

            }
        }
    }


    @Autowired
    private IControlBayonetMidService iControlBayonetMidService;


    @Autowired
    private ApiDeelService apiDeelService;

    /**
     * 人物轨迹信息  TODO 後續記得加上token
     */
    @Scheduled(fixedDelay = 1000 * 60, initialDelay = 10000)
    public void bayonetTrack() {
        log.error("轨迹检测开始");
        //获取布控摄像头的列表
        List<CameraInfoVO> cameraList = iControlBayonetMidService.selectCameraByTask();
        if (UtilValidate.isEmpty(cameraList)) {
            return;
        }
        String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis());
//        CameraInfoVO cameraInfoVO = cameraList.get(0);
//        System.out.println(cameraInfoVO);
//        cameraList.clear();
//        cameraInfoVO.setIdFaceCamera("1210110089958686721");
//        cameraList.add(cameraInfoVO);
//        log.error("摄像头类别"+gson.toJson(cameraList));
        cameraList.forEach(a ->
        {
            //不存在摄像头数据了
            if (!redisUtils.exists(RedisKeys.getCameraByTrack(nowTime, a.getIdFaceCamera()))) {
                FaceLibraryVO faceLibraryVO = new FaceLibraryVO();
                faceLibraryVO.setName("摄像头库" + nowTime + ":" + a.getIdFaceCamera());
                faceLibraryVO = apiDeelService.addLib(faceLibraryVO);  //暂时去掉
//                faceLibraryVO=new FaceLibraryVO();
//                faceLibraryVO.setLibraryId(a.getIdFaceCamera());
                if (UtilValidate.isNotEmpty(faceLibraryVO)) {
                    //创建人脸库 使用时间+摄像头id
                    //给redis赋值
                    //每个摄像头创建一个线程一直运行程序检测时间如果不是当天则自动关闭
                    //关联新建的库id和一些基本信息
                    BayOnetCameraVO bayOnetCameraVO = new BayOnetCameraVO(a.getIdFaceCamera(), faceLibraryVO.getLibraryId().toString(), 0L, new ArrayList<>());
                    redisUtils.set(RedisKeys.getCameraByTrack(nowTime, a.getIdFaceCamera()), gson.toJson(bayOnetCameraVO));
                    //运行一个线程检索的方法
                    asyncContral.trackByCamera(nowTime, a.getIdFaceCamera());
                    log.error("运行检测的方法：{},{}", nowTime, a.getIdFaceCamera());
                    return;
                }
            } else {
                //利用redis的过期来判定任务是否异常退出
                //30秒过期
                if (!redisUtils.exists(RedisKeys.getCameraByExpired(nowTime, a.getIdFaceCamera()))) {
                    //运行一个线程检索的方法
                    log.error("过期时候运行检测的方法：{},{}", nowTime, a.getIdFaceCamera());
                    asyncContral.trackByCamera(nowTime, a.getIdFaceCamera());
                }
            }
        });
    }


}
